home *** CD-ROM | disk | FTP | other *** search
- #!/usr/local/apps/perl/bin/perl
- #############################################################################
- # #
- # WHO: John L. Moreland #
- # #
- # WHAT: obj2wrl #
- # #
- # WHY: Converts a wavefront OBJ file to a VRML file. #
- # #
- # WHERE: San Diego Supercomputer Center (SDSC) #
- # #
- # WHEN: Wed Mar 15 13:00:23 PST 1995 (ORIGINAL) #
- # Tue Apr 11 10:15:36 PST 1995 (CURRENT) #
- # #
- # HOW: Perl #
- # #
- #############################################################################
- # #
- # Copyright (c) 1995 San Diego Supercomputer Center (SDSC) #
- # a division of General Atomics, San Diego, California, USA #
- # #
- # Users and possessors of this source code are hereby granted a #
- # nonexclusive, royalty-free copyright and design patent license to #
- # use this code in individual software. License is not granted for #
- # commercial resale, in whole or in part, without prior written #
- # permission from SDSC. This source is provided "AS IS" without #
- # express or implied warranty of any kind. #
- # #
- # For further information contact: #
- # E-Mail: info@sds.sdsc.edu #
- # #
- # Surface Mail: Information Center #
- # San Diego Supercomputer Center #
- # P.O. Box 85608 #
- # San Diego, CA 92138-5608 #
- # (619) 534-5000 #
- # #
- #############################################################################
-
-
- #############################################################################
- ################################ SUBROUTINES ##############################
- #############################################################################
-
-
- #############################################################################
- # #
- # Returns the maximum of all values passed in. #
- # #
- #############################################################################
- sub max
- {
- local( $result ) = pop( @_ );
- foreach $item ( @_ )
- {
- $result = $item if $item > $result;
- }
- return( $result );
- }
-
-
- #############################################################################
- # #
- # Returns the minimum of all values passed in. #
- # #
- #############################################################################
- sub min
- {
- local( $result ) = pop( @_ );
- foreach $item ( @_ )
- {
- $result = $item if $item < $result;
- }
- return( $result );
- }
-
-
- #############################################################################
- # #
- # Returns the absolute value of the number passed in. #
- # #
- #############################################################################
- sub abs
- {
- local( $result ) = $_[0];
- $result *= -1 if $result < 0;
- return( $result );
- }
-
-
- #############################################################################
- ################################### INIT ##################################
- #############################################################################
-
-
- #############################################################################
- # SET DEFAULT VARIABLE VALUES
-
- $nLines = 0; # Number of lines read from input file
-
- $nVerts = 0; # Number of verticies parsed out of the input file
- $nPolys = 0; # Number of face-sets parsed out of the input file
- $nSNorms = 0; # Number of surface-normals parsed out of the input file
- $nTNorms = 0; # Number of texture-normals parsed out of the input file
-
- $input_name = "STDIN"; # The input file name
- $output_name = "STDOUT"; # The output file name
- $verbose_name = "/dev/null"; # The verbose-message file name
-
- $x_max = ""; # Max of all X-Coordinate vertex values
- $x_min = ""; # Min of all X-Coordinate vertex values
- $y_max = ""; # Max of all Y-Coordinate vertex values
- $y_min = ""; # Min of all Y-Coordinate vertex values
- $z_max = ""; # Max of all Z-Coordinate vertex values
- $z_min = ""; # Min of all Z-Coordinate vertex values
- $x_range = 0.0; # MaxX - MinX
- $x_center = 0.0; # (MaxX+MinX)/2
- $y_range = 0.0; # MaxY - MinY
- $y_center = 0.0; # (MaxY+MinY)/2
- $z_range = 0.0; # MaxZ - MinZ
- $z_center = 0.0; # (MaxZ+MinZ)/2
- $data_max = 0.0; # MAX OF x_max, y_max, z_max
- $data_min = 0.0; # MIN OF x_max, y_max, z_max
- $data_center = 0.0;
- $data_range = 0.0;
-
- $normalize = 0; # Should we normalize the data ? (default=NO)
- $x_scale = 1.0; # Scale factor for X-Axis
- $y_scale = 1.0; # Scale factor for Y-Axis
- $z_scale = 1.0; # Scale factor for Z-Axis
- $colorize = 0; # Should we color the data by depth ? (default=NO)
-
-
- #############################################################################
- # PARSE COMMAND LINE
-
- while ( @ARGV )
- {
- $option = shift( @ARGV );
-
- if ( $option eq "-infile" )
- {
- $input_name = shift( @ARGV );
- }
- elsif ( $option eq "-outfile" )
- {
- $output_name = shift( @ARGV );
- }
- elsif ( $option eq "-verbose" )
- {
- $verbose_name = "STDERR";
- }
- elsif ( $option eq "-normalize" )
- {
- $normalize = 1;
- }
- elsif ( $option eq "-colorize" )
- {
- $colorize = 1;
- }
- elsif ( $option eq "-xscale" )
- {
- $x_scale = shift( @ARGV );
- }
- elsif ( $option eq "-yscale" )
- {
- $y_scale = shift( @ARGV );
- }
- elsif ( $option eq "-zscale" )
- {
- $z_scale = shift( @ARGV );
- }
- elsif ( ! ( $option =~ /^-/ ) )
- {
- # Allow input and output file names to be specified
- # without the lame option flags. Just parse filenames out.
- if ( $input_name eq "STDIN" )
- {
- if ( ! -f $option )
- {
- print STDERR "Infile does not exist: $option\n";
- exit( 1 );
- }
- $input_name = $option;
- }
- elsif ( $output_name eq "STDOUT" )
- {
- $output_name = $option;
- }
- else
- {
- print STDERR "Too many files specified: $option\n";
- exit( 1 );
- }
- }
- else
- {
- print STDERR "Unknown option $option\n";
- print STDERR "Usage: $0 [arguments]\n";
- print STDERR " [-infile inputfile]\n";
- print STDERR " default is STDIN\n";
- print STDERR " [-outfile outputfile]\n";
- print STDERR " default is STDOUT\n";
- print STDERR " -verbose\n";
- print STDERR " default is OFF\n";
- print STDERR " -normalize\n";
- print STDERR " default is OFF\n";
- print STDERR " -colorize\n";
- print STDERR " default is OFF\n";
- print STDERR " -xscale float\n";
- print STDERR " default is 1.0\n";
- print STDERR " -yscale float\n";
- print STDERR " default is 1.0\n";
- print STDERR " -zscale float\n";
- print STDERR " default is 1.0\n";
- exit( 1 );
- }
- }
-
- if ( $input_name eq "STDIN" )
- {
- open( INPUT, "<&STDIN" );
- }
- else
- {
- open( INPUT, "<$input_name" );
- }
-
- if ( $output_name eq "STDOUT" )
- {
- open( OUTPUT, ">&STDOUT" );
- }
- else
- {
- open( OUTPUT, ">$output_name" );
- }
-
- if ( $verbose_name eq "STDERR" )
- {
- open( VERBOSE, ">&STDERR" );
- }
- else
- {
- open( VERBOSE, ">$verbose_name" );
- }
-
- print VERBOSE "Using $input_name for input and $output_name for output...\n";
-
-
- #############################################################################
- ################################### MAIN ##################################
- #############################################################################
-
-
- #############################################################################
- # READ THE FILE INTO OUR "OBJ" LIST
-
- print VERBOSE "Reading $input_name... ";
-
- @OBJ = <INPUT>;
- $nLines = $#OBJ + 1;
-
- print VERBOSE "($nLines lines read)\n";
-
- close( INPUT );
-
-
- #############################################################################
- # PARSE OUT: VERTICIES, POLYGONS, SURFACE NORMALS, AND TEXTURE NORMALS
-
- print VERBOSE "Extracting data...\n";
-
- for ( $i=0; $i<$nLines; $i++ )
- {
- chop( $line = $OBJ[$i] );
-
- next if ( $line =~ /^#/ ); # Skip comments
- next if ( $line =~ /^$/ ); # Skip blank lines
-
- if ( $line =~ /^v / )
- {
- ( $v, $x, $y, $z, @junk ) = split( /\s+/, $line );
- $vertices{$nVerts} = join( " ", $x, $y, $z );
-
- if ( $x_max eq "" )
- {
- $x_max = $x;
- $x_min = $x;
- $y_max = $y;
- $y_min = $y;
- $z_max = $z;
- $z_min = $z;
- }
- else
- {
- $x_max = &max( $x_max, $x );
- $x_min = &min( $x_min, $x );
- $y_max = &max( $y_max, $y );
- $y_min = &min( $y_min, $y );
- $z_max = &max( $z_max, $z );
- $z_min = &min( $z_min, $z );
- }
-
- $nVerts++;
- }
- elsif ( $line =~ /^f / )
- {
- @temp1 = split( /\s+/, $line );
- shift( @temp1 ); # Toss the "f "
- @temp2 = ();
- for ( $j=0; $j<=$#temp1; $j++ )
- {
- ( $index, @junk ) = split( /\//, $temp1[$j] );
- $index -= 1;
- if ( $input_name =~ /eel/ ) { $index += 1; } # HACK
- @temp2 = ( @temp2, $index );
- }
-
- $connections{$nPolys} = join( " ", @temp2 );
-
- $nPolys++;
- }
- elsif ( $line =~ /^vt / )
- {
- }
- elsif ( $line =~ /^vn / )
- {
- }
- else
- {
- }
-
- }
-
- print VERBOSE " Verticies: $nVerts\n";
- print VERBOSE " Polygons: $nPolys\n";
-
- #############################################################################
- # CALCULATE DATA STATISTICS
-
- print VERBOSE "Calculating data statistics...\n";
-
- $x_range = &abs( $x_max - $x_min );
- $x_center = ($x_max + $x_min) / 2.0;
-
- $y_range = &abs( $y_max - $y_min );
- $y_center = ($y_max + $y_min) / 2.0;
-
- $z_range = &abs( $z_max - $z_min );
- $z_center = ($z_max + $z_min) / 2.0;
-
- $data_max = &max( $x_max, $y_max, $z_max );
- $data_min = &min( $x_min, $y_min, $z_min );
- $data_center = ($data_max + $data_min) / 2.0;
- $data_range = &max( $x_range, $y_range, $z_range );
-
- $normalization = $data_range / 2.0;
-
- print VERBOSE " x_max = $x_max\n";
- print VERBOSE " x_min = $x_min\n";
- print VERBOSE " x_center = $x_center\n";
- print VERBOSE " x_range = $x_range\n";
- print VERBOSE "\n";
- print VERBOSE " y_max = $y_max\n";
- print VERBOSE " y_min = $y_min\n";
- print VERBOSE " y_center = $y_center\n";
- print VERBOSE " y_range = $y_range\n";
- print VERBOSE "\n";
- print VERBOSE " z_max = $z_max\n";
- print VERBOSE " z_min = $z_min\n";
- print VERBOSE " z_center = $z_center\n";
- print VERBOSE " z_range = $z_range\n";
- print VERBOSE "\n";
- print VERBOSE " data_max = $data_max\n";
- print VERBOSE " data_min = $data_min\n";
- print VERBOSE " data_center = $data_center\n";
- print VERBOSE " data_range = $data_range\n";
- print VERBOSE "Done calculating data statistics.\n";
-
- #############################################################################
- # WRITE VRML
-
- print VERBOSE "Writting $output_name...\n";
-
- print OUTPUT "#VRML V1.0 ascii\n";
- print OUTPUT "\n";
- print OUTPUT "Separator {\n";
-
- print OUTPUT "\tSeparator {\n";
- print OUTPUT "\t\tTransform { rotation -1 0 0 3.0 }\n";
- # print OUTPUT "\t\tLightModel { model BASE_COLOR }\n";
-
- if ( $colorize )
- {
- print OUTPUT "\t\tMaterialBinding { value PER_VERTEX_INDEXED }\n";
-
- #####################################################################
- # WRITE MATERIAL TABLE
-
- print OUTPUT "\t\tMaterial {\n";
- print OUTPUT "\t\t\tdiffuseColor [\n";
-
- for ( $i=0; $i<$nVerts; $i++ )
- {
- # DEREFERENCE A VERTICY
-
- @vert = split( /\s+/, $vertices{$i} );
-
- # COLORIZE THE DATA
- if ( $z_range != 0 ) { $vert[2] /= ($z_range / 2.0); }
- $red = 0.0;
- $green = 1.0-$vert[2]/-1.5;
- $blue = 0.5+$vert[2]/-1.5;
-
- if ( $vert[2] == 0.0 )
- {
- $red = 0.0;
- $green = 0.25;
- $blue = 0.0;
- }
-
- # OUTPUT THE DATA
-
- print OUTPUT "\t\t\t\t";
- printf( OUTPUT "%f %f %f", $red, $green, $blue );
- if ( $i == $nVerts - 1 )
- {
- print OUTPUT "\n";
- } else {
- print OUTPUT ",\n";
- }
- }
- printf OUTPUT "\t\t\t]\n";
- printf OUTPUT "\t\t}\n";
- }
-
- #############################################################################
- # WRITE VERTEXT DATA
-
- print OUTPUT "\t\tCoordinate3 {\n";
- print OUTPUT "\t\t\tpoint [\n";
-
- for ( $i=0; $i<$nVerts; $i++ )
- {
- # DEREFERENCE A VERTICY
-
- @vert = split( /\s+/, $vertices{$i} );
-
- if ( $normalize == 1 )
- {
- # CENTER THE DATA
- $vert[0] -= $x_center;
- $vert[1] -= $y_center;
- $vert[2] -= $z_center;
-
- # NORMALIZE THE DATA
- $vert[0] /= $normalization;
- $vert[1] /= $normalization;
- $vert[2] /= $normalization;
- }
-
- # SCALE THE DATA
- if ( $x_scale != 1.0 ) { $vert[0] *= $x_scale; }
- if ( $y_scale != 1.0 ) { $vert[1] *= $y_scale; }
- if ( $z_scale != 1.0 ) { $vert[2] *= $z_scale; }
-
- # OUTPUT THE DATA
-
- print OUTPUT "\t\t\t\t";
- printf( OUTPUT "%f %f %f", $vert[0], $vert[1], $vert[2] );
- if ( $i == $nVerts - 1 )
- {
- print OUTPUT "\n";
- } else {
- print OUTPUT ",\n";
- }
- }
- printf OUTPUT "\t\t\t]\n";
- printf OUTPUT "\t\t}\n";
-
- #############################################################################
- # WRITE CONNECTIVITY DATA
-
- print OUTPUT "\t\tIndexedFaceSet {\n";
- print OUTPUT "\t\t\tcoordIndex [\n";
-
- for ( $i=0; $i<$nPolys; $i++ )
- {
- # EXTRACT THE NEXT SET OF VERTICIES FOR A NEW QUAD
-
- @cons = split( /\s+/, $connections{$i} );
-
- print OUTPUT "\t\t\t\t";
-
- for ( $j=0; $j<=$#cons; $j++ )
- {
- # $cons[$j] -= 1; ALREADY DONE IN EXTRACTION STEP
- print OUTPUT "$cons[$j], ";
- }
- print OUTPUT "-1";
-
- if ( $i == $nPolys - 1 )
- {
- print OUTPUT "\n";
- } else {
- print OUTPUT ",\n";
- }
-
- }
-
- print OUTPUT "\t\t\t]\n";
- print OUTPUT "\t\t}\n";
- print OUTPUT "\t}\n";
-
- #############################################################################
- # DONE
-
- print OUTPUT "}\n";
-
- close( OUTPUT );
-
- print VERBOSE "Done writting $output_name...\n";
-
- print VERBOSE "Done\n";
-
-